#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <pthread.h>
#include <queue>
#include <vector>
#include "locker.h"
#include <iostream>

using namespace std;

// 线程池类
template<typename T>
class threadpool
{
public:
    threadpool(int thread_pool_idx, int thread_number=8, int max_requests = 10000);
    ~threadpool();

    bool append(T* request); // 添加任务

private:
    static void* worker(void* arg); // 线程函数必须是静态函数
    void run();

private:
    // 线程的数量
    int m_thread_number;
    // 线程池数组，大小为m_thread_number
    vector<pthread_t> m_threads;  
    // 请求队列中最多允许的等待处理的请求数量
    int m_max_requests;
    // 请求队列
    queue<T*> m_workqueue;
    // 互斥锁
    locker m_queuelocker;
    // 用信号量来标识请求队列中的请求数 用来判断是否有任务需要处理 
    sem m_queuestat;
    // 是否结束线程
    bool m_stop;
    // 线程池编号
    int poolIdx;
    //  超出等待数量
    int over_num=0;
};


template<typename T>
threadpool<T>::threadpool(int thread_pool_idx, int thread_number, int max_requests):
    m_thread_number(thread_number),
    m_max_requests(max_requests),
    poolIdx(thread_pool_idx),
    m_stop(false)
{
    if(thread_number<=0||max_requests<=0){
        throw exception();
    }

    m_threads = vector<pthread_t>(m_thread_number);
    if(m_threads.empty()){
        throw exception();
    }

    // 创建thread_number个线程，并将它们设置为线程脱离
    for(int i=0;i<thread_number;++i){
        cout <<  "creating the " << i << "dt thead" << endl;
        // 将this作为参数传递给worcker，以解决static函数访问不了非静态成员的问题
        if(pthread_create(&m_threads[i], nullptr, worker, this)!=0){
            throw exception();
        }
        // 将线程设置成脱离态后，当这一线程运行结束时，它的资源会被系统自动回收，而不再需要在其它线程中对其进行pthread_join()操作
        if(pthread_detach(m_threads[i])){
            throw exception();
        }
    }
}

template<typename T>
threadpool<T>::~threadpool(){
    m_stop = true;  // 强行停止线程
}

template<typename T>
bool threadpool<T>::append(T* request){

    m_queuelocker.lock();
    if(m_workqueue.size()>m_max_requests){  // 超出最多等待数量
        m_queuelocker.unlock();
        ++over_num;
        cout << "pool_" << poolIdx << ": "<< over_num << endl;
        return false;
    }
    m_workqueue.push(request);
    m_queuelocker.unlock();

    m_queuestat.post(); // 信号量增加
    return true;
}


template<typename T>
void* threadpool<T>::worker(void* arg){
    threadpool* pool = (threadpool*)arg;
    pool->run();
    return pool;
}

template<typename T>
void threadpool<T>::run(){
    while(!m_stop){
        m_queuestat.wait(); // 等待一个请求队列中待处理的HTTP请求
        m_queuelocker.lock();
        if(m_workqueue.empty()){    // 没有待处理的信号量
            m_queuelocker.unlock();
            continue;
        }
        // cout<<"run:得到一个信号量,线程将执行process"<< " pool_" << poolIdx<<endl;
        T* request = m_workqueue.front();
        m_workqueue.pop();
        m_queuelocker.unlock();

        if(!request){
            continue;
        }
        if(poolIdx==1) // IO线程池，处理读写事件
            request->process1(); 
        if(poolIdx==2) // 逻辑线程池，处理HTTP请求
            request->process2(); 
    }
}




#endif